package cn.jsj.machine.service.impl;

import cn.jsj.machine.dao.IMachineDao;
import cn.jsj.machine.dao.IPartDao;
import cn.jsj.machine.exceptions.MyRuntimeIdentityException;
import cn.jsj.machine.exceptions.MyRuntimeParamsException;
import cn.jsj.machine.pojo.CMachine;
import cn.jsj.machine.pojo.CPart;
import cn.jsj.machine.service.MachineService;
import cn.jsj.machine.service.PartService;
import cn.jsj.machine.service.UserService;
import org.hibernate.validator.constraints.Length;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.util.List;

import static org.springframework.transaction.annotation.Isolation.REPEATABLE_READ;

@Service
public class PartServiceImpl implements PartService {

    @Autowired
    private UserService userService;

    @Autowired
    private IMachineDao machineDao;

    @Autowired
    private MachineService machineService;

    @Autowired
    private IPartDao partDao;

    @Override
    @Transactional(propagation = Propagation.REQUIRED, isolation = REPEATABLE_READ)
    public void addOnePart(Integer account, String password, String partName, Integer remainNumber, Integer limitNumber, Double rbm){
        Integer i = this.userService.userLogin(account, password);
        if(i == -1){
            throw new MyRuntimeIdentityException("身份验证错误");
        }
        CPart part = this.partDao.getOnePartByName(partName.trim());
        if(part != null){
            throw new MyRuntimeParamsException("您已经添加过该名称的原料，请勿重复添加");
        }
        this.partDao.addOnepart(partName.trim(),remainNumber,limitNumber,rbm);
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, isolation = REPEATABLE_READ)
    public List<CPart> getPartList(Integer account, String password) {
        Integer i = this.userService.userLogin(account, password);
        if(i == -1){
            throw new MyRuntimeIdentityException("用户身份认证有误");
        }
        return this.partDao.getAllparts();
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, isolation = REPEATABLE_READ)
    public List<CMachine> getMachineListByOnePart(Integer partID) {
        return this.machineDao.getMachineListUseOfPart(partID);
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, isolation = REPEATABLE_READ)
    public void resetPartWaringValue(Integer account, String password, Integer partID, Integer partValue){
        Integer i = this.userService.userLogin(account, password);
        if(i == -1){
            throw new MyRuntimeIdentityException("用户身份认证有误");
        }
        this.partDao.resetWaringValueOfPart(partID,partValue);
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, isolation = REPEATABLE_READ)
    public void resetRmbOfPart(@NotNull @Min(value = 1) Integer account, @NotBlank @Length(min = 5, max = 15) String password, @NotNull @Min(value = 1) Integer partID, @NotNull @Min(value = 0) @Max(value = 999999999) Double newRmb) {
        Integer i = this.userService.userLogin(account, password);
        if(i == -1){
            throw new MyRuntimeIdentityException("用户身份认证有误");
        }
        CPart part = this.partDao.getOnePartByID(partID);
        if(part == null){
            throw new MyRuntimeParamsException("原料信息不存在,请刷新后再试");
        }
        if(part.getRmb() == newRmb){
            throw new MyRuntimeParamsException("单价未发生改变");
        }
        List<CMachine> machines = this.machineDao.getMachineListUseOfPart(part.getPartID());
        if(machines != null && machines.size() > 0){
            for(CMachine m: machines){
                Integer neednumber = this.machineDao.getPartNeedNumberOfMachine(m.getMachineID(),part.getPartID());
                if(neednumber == null){
                    continue;
                }else{
                    if(newRmb * neednumber > part.getRmb() * neednumber){
                        this.machineDao.addMachineValue(m.getMachineID(),newRmb * neednumber - part.getRmb() * neednumber);
                    }else{
                        this.machineDao.reduceMachineValue(m.getMachineID(),part.getRmb() * neednumber - newRmb * neednumber);
                    }
                }
            }
        }
        this.partDao.resetRmbOfPart(part.getPartID(),newRmb);
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, isolation = REPEATABLE_READ)
    public void addPartNumber(@NotNull @Min(value = 1) Integer account, @NotBlank @Length(min = 5, max = 15) String password, @NotNull @Min(value = 1) Integer partID, @NotNull @Min(value = 0) Integer addNumber) {
        Integer i = this.userService.userLogin(account, password);
        if(i == -1){
            throw new MyRuntimeIdentityException("用户身份认证有误");
        }
        CPart part = this.partDao.getOnePartByID(partID);
        if(part == null){
            throw new MyRuntimeParamsException("原料信息不存在,请刷新后再试");
        }
        if(part.getRemaining() + addNumber > 999999999){
            throw new MyRuntimeParamsException("数量溢出，添加失败");
        }
        this.partDao.addNumberOfPart(part.getPartID(),addNumber);
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, isolation = REPEATABLE_READ)
    public void cutPartNumber(Integer account, String password, Integer partID, Integer cutNumber) {
        Integer i = this.userService.userLogin(account, password);
        if(i == -1){
            throw new MyRuntimeIdentityException("用户身份认证有误");
        }
        CPart part = this.partDao.getOnePartByID(partID);
        if(part == null){
            throw new MyRuntimeParamsException("原料信息不存在,请刷新后再试");
        }
        if(part.getRemaining() < cutNumber){
            throw new MyRuntimeParamsException("原料剩余量不足，无法修改库存信息");
        }else{
            this.partDao.cutNumberOfPart(part.getPartID(),cutNumber);
        }
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, isolation = REPEATABLE_READ)
    public void resetPartName(Integer account, String password, Integer partID, String newName) {
        Integer i = this.userService.userLogin(account, password);
        if(i == -1){
            throw new MyRuntimeIdentityException("用户身份认证有误");
        }
        i = this.partDao.renameOfPart(partID,newName.trim());
        if( i != 1){
            throw new MyRuntimeParamsException("参数有误");
        }
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, isolation = REPEATABLE_READ)
    public void deleteOnePartInformation(Integer account, String password, Integer partID){
        Integer i = this.userService.userLogin(account, password);
        if(i == -1){
            throw new MyRuntimeIdentityException("用户身份认证有误");
        }
        List<CMachine> machines = this.machineDao.getMachineListUseOfPart(partID);
        if(machines != null && machines.size()>0){
            String inf = null;
            if(machines.size() == 1){
                inf = new String("该原料在"+machines.get(0).getMachineName()+"中使用，请先修改产品原料信息");
            }else {
                inf = new String("该原料在"+machines.get(0).getMachineName()+"等产品中使用，请先修改产品原料信息");
            }
            throw new MyRuntimeParamsException(inf);
        }
        i = this.partDao.deleteOnePart(partID);
        if(i != 1){
            throw  new MyRuntimeParamsException("参数有误");
        }
    }
}
